/**
 * tabs - jQuery xui
 *
 * Licensed under the GPL: http://www.gnu.org/licenses/gpl.txt
 *
 * Copyright 2013 xjb [ beymy.en@gmail.com ]
 *
 */
(function($) {
    // 自动设置tabs的大小
    function setSize(container) {
        var opts = $.data(container, 'tabs').options;
        var cc = $(container);
        if (opts.fit == true) {
            var p = cc.parent();
            opts.width = p.width();
            opts.height = p.height();
        }
        cc.width(opts.width).height(opts.height);

        var header = $('>div.tabs-header', container);
        header.width(cc.width() - (cc.outerWidth() - cc.width));

        var panels = $('>div.tabs-panels', container);
        var height = opts.height;
        if (!isNaN(height)) {
            panels._outerHeight(height - header.outerHeight());
        } else {
            panels.height('auto');
        }
        var width = opts.width;
        if (!isNaN(width)) {
            panels._outerWidth(width);
        } else {
            panels.width('auto');
        }
    }

    // 构建tabs的header和body
    function buildTabs(container) {
        var opts = $.data(container, 'tabs').options;

        $(container).addClass('tabs-container');
        $(container).wrapInner('<div class="tabs-panels"></div>');
        $('<div class="tabs-header"><ul class="tabs"></ul></div>').prependTo(container);

        var header = $('>div.tabs-header', container);
        var panels = $('>div.tabs-panels', container);

        if (opts.plain == true) {
            header.addClass('tabs-header-plain');
        } else {
            header.removeClass('tabs-header-plain');
        }

        if (opts.border == true) {
            header.removeClass('tabs-header-noborder');
            panels.removeClass('tabs-panels-noborder');
        } else {
            header.addClass('tabs-header-noborder');
            panels.addClass('tabs-panels-noborder');
        }

        $('>div.tabs-panels>div', container).each(function() {
            if (!$(this).attr('id')) {
                $(this).attr('id', 'gen-tabs-panel' + $.fn.tabs.defaults.idSeed++);
            }

            var options = $.extend({}, $.parser.parseOptions(this, ['id', 'title']));
            createTab(container, options);
        });
    }

    function bindTabsEvents(container) {
        var opts = $.data(container, 'tabs').options;
        var header = $('>div.tabs-header', container);
        var panels = $('>div.tabs-panels', container);
        var tabs = $('ul.tabs', header);

        $(container).bind('resize', function() {
            var opts = $.data(container, 'tabs').options;
            if (opts.fit == true) {
                setSize(container);
            }
            return false;
        });

        $('li', tabs).unbind('.tabs').bind('click.tabs', function() {
            $('.tabs-selected', tabs).removeClass('tabs-selected');
            $(this).addClass('tabs-selected');
            $(this).blur();

            $('>div.tabs-panels>div', container).css('display', 'none');

            var tabAttr = $.data(this, 'tabs.tab');
            var panel = $('#' + tabAttr.id);
            panel.css('display', 'block');

            if (tabAttr.href && (!tabAttr.loaded || !tabAttr.cache)) {
                panel.load(tabAttr.href, null, function() {
                    if ($.parser) {
                        $.parser.parse(panel);
                    }
                    opts.onLoad.apply(this, arguments);
                    tabAttr.loaded = true;
                });
            }

            opts.onSelect.call(panel, tabAttr.title);
        });

        $('a.tabs-close', tabs).unbind('.tabs').bind('click.tabs', function() {
            var elem = $(this).parent()[0];
            var tabAttr = $.data(elem, 'tabs.tab');
            closeTab(container, tabAttr.title);
        });
    }

    function createTab(container, options) {
        var header = $('>div.tabs-header', container);
        var tabs = $('ul.tabs', header);

        var tab = $('<li></li>');
        var tabTitle = $('<span class="tabs-title"></span>').html(options.title);
        var tabHeader = $('<a href="javascript:void(0)" class="tabs-inner"></a>').append(tabTitle);
        tab.append(tabHeader).appendTo(tabs);

        if (options.closable) {
            tabTitle.addClass('tabs-closable');
            tabHeader.after('<a href="javascript:void(0)" class="tabs-close"></a>');
        }
        if (options.icon) {
            tabTitle.addClass('tabs-with-icon');
            tabTitle.after($('<span class="tabs-icon"></span>').addClass(options.icon));
        }
        if (options.selected) {
            tab.addClass('tabs-selected');
        }
        if (options.content) {
            $('#' + options.id).html(options.content);
        }

        $('#' + options.id).removeAttr('title');
        $.data(tab[0], 'tabs.tab', {
            id: options.id,
            title: options.title,
            href: options.href,
            loaded: false,
            cache: options.cache
        });
    }

    function addTab(container, options) {
        options = $.extend({
            id: null,
            title: '',
            content: '',
            href: null,
            cache: true,
            icon: null,
            closable: false,
            selected: true,
            height: 'auto',
            width: 'auto'
        }, options || {});

        if (options.selected) {
            $('.tabs-header .tabs li', container).removeClass('tabs-selected');
        }
        options.id = options.id || 'gen-tabs-panel' + $.fn.tabs.defaults.idSeed++;

        $('<div></div>').attr('id', options.id).attr('title', options.title).height(options.height).width(options.width).appendTo($('>div.tabs-panels',
            container));

        createTab(container, options);
    }

    // 根据title关闭tab
    function closeTab(container, title) {
        var opts = $.data(container, 'tabs').options;
        var elem = $('>div.tabs-header li:has(a span:contains("' + title + '"))', container)[0];
        if (!elem)
            return;

        var tabAttr = $.data(elem, 'tabs.tab');
        var panel = $('#' + tabAttr.id);

        if (opts.onClose.call(panel, tabAttr.title) == false)
            return;

        var selected = $(elem).hasClass('tabs-selected');
        $.removeData(elem, 'tabs.tab');
        $(elem).remove();
        panel.remove();

        setSize(container);
        if (selected) {
            selectTab(container);
        }
    }

    // 激活选中的tab,如果没有选中的激活第一个tab
    function selectTab(container, title) {
        if (title) {
            var elem = $('>div.tabs-header li:has(a span:contains("' + title + '"))', container)[0];
            if (elem) {
                $(elem).trigger('click');
            }
        } else {
            var tabs = $('>div.tabs-header ul.tabs', container);
            if ($('.tabs-selected', tabs).length == 0) {
                $('li:first', tabs).trigger('click');
            } else {
                $('.tabs-selected', tabs).trigger('click');
            }
        }
    }

    function exists(container, title) {
        return $('>div.tabs-header li:has(a span:contains("' + title + '"))', container).length > 0;
    }

    $.fn.tabs = function(options, param) {
        if (typeof options == 'string') {
            return $.fn.tabs.methods[options](this, param);
        }

        options = options || {};

        return this.each(function() {
            var state = $.data(this, 'tabs');
            var opts;
            if (state) {
                opts = $.extend(state.options, options);
            } else {
                opts = $.extend({}, $.fn.tabs.defaults, $.fn.tabs.parseOptions(this), options);
                $.data(this, 'tabs', {
                    options: opts
                });

                buildTabs(this);
            }

            bindTabsEvents(this);
            setSize(this);
            selectTab(this);
        });
    };

    $.fn.tabs.methods = {
        'resize': function(jq) {
            return jq.each(function() {
                setSize(this);
            });
        },
        'add': function(jq, param) {
            return jq.each(function() {
                addTab(this, param);
                $(this).tabs();
            });
        },
        'close': function(jq, param) {
            return jq.each(function() {
                closeTab(this, param);
            });
        },
        'select': function(jq, param) {
            return jq.each(function() {
                selectTab(this, param);
            });
        },
        'exists': function(jq, param) {
            return exists(jq[0], param);
        }
    };

    $.fn.tabs.parseOptions = function(target) {
        return $.extend({}, $.parser.parseOptions(target, [
            'width', 'height', {
                fit: 'boolean',
                plain: 'boolean',
                border: 'boolean'
            }
        ]));
    };

    $.fn.tabs.defaults = {
        width: 'auto',
        height: 'auto',
        idSeed: 0,
        plain: false,
        fit: false,
        border: true,
        scrollIncrement: 100,
        scrollDuration: 400,
        onLoad: function() {},
        onSelect: function(title) {},
        onClose: function(title) {}
    };
})(jQuery);
